package com.atguigu.tingshu.order.listener;

import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.constant.TingShuMqConstants;
import com.atguigu.tingshu.common.service.RabbitmqService;
import com.atguigu.tingshu.model.order.OrderDetail;
import com.atguigu.tingshu.model.order.OrderInfo;
import com.atguigu.tingshu.order.mapper.OrderDetailMapper;
import com.atguigu.tingshu.order.service.OrderInfoService;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.rabbitmq.client.Channel;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
public class OrderMqListener {
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private OrderInfoService orderInfoService;
    @Resource
    private OrderDetailMapper orderDetailMapper;
    @Resource
    private RabbitmqService rabbitmqService;

    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = TingShuMqConstants.ORDER_EXCHANGE, type = ExchangeTypes.TOPIC, ignoreDeclarationExceptions = "ture"),
            value = @Queue(value = TingShuMqConstants.ORDER_STATUS_QUEUE),
            key = TingShuMqConstants.ORDER_STATUS_RK
    ))
    public void updateStatusListener(String orderNo, Channel channel, Message message) throws IOException {
        if (StringUtils.isBlank(orderNo)) {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            return;
        }
        //幂等性校验
        String itemKey = RedisConstant.ORDER_STATUS_ITEM_PREFIX + orderNo;
        Boolean flag = this.redisTemplate.opsForValue().setIfAbsent(itemKey, "", RedisConstant.ITEM_TIMEOUT, TimeUnit.SECONDS);
        if (Boolean.FALSE.equals(flag)) {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            return;
        }
        //获取订单信息
        OrderInfo orderInfo = this.orderInfoService.getOne(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderNo, orderNo));
        try {
            //执行业务,修改订单支付状态
            boolean b = this.orderInfoService.updateOrderStatus(orderNo, SystemConstant.ORDER_STATUS_UNPAID, SystemConstant.ORDER_STATUS_PAID);
            if (b) {
                //获取订单详情中itemId集合
                List<Long> itemIdList = this.orderDetailMapper.selectList(new LambdaQueryWrapper<OrderDetail>()
                        .eq(OrderDetail::getOrderId, orderInfo.getId())).stream().map(OrderDetail::getItemId).toList();
                //封装消息内容
                UserPaidRecordVo userPaidRecordVo = new UserPaidRecordVo();
                userPaidRecordVo.setOrderNo(orderNo);
                userPaidRecordVo.setUserId(orderInfo.getUserId());
                userPaidRecordVo.setItemType(orderInfo.getItemType());
                userPaidRecordVo.setItemIdList(itemIdList);
                //发送消息，保存记录信息
                this.rabbitmqService.sendMqMsg(TingShuMqConstants.USER_EXCHANGE, TingShuMqConstants.USER_RECORD_RK, JSON.toJSONString(userPaidRecordVo));
            } else {
                if (SystemConstant.ORDER_PAY_ACCOUNT.equals(orderInfo.getPayWay())) {
                    //发消息，退款
                    this.rabbitmqService.sendMqMsg(TingShuMqConstants.ORDER_EXCHANGE, TingShuMqConstants.ACCOUNT_REFUND_RK, orderNo);
                }
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            if (message.getMessageProperties().getRedelivered()) {
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
            } else {
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            }
        }
    }

    @RabbitListener(queues = TingShuMqConstants.ORDER_DEAD_QUEUE)
    public void closeOrder(String orderNo, Channel channel, Message message) throws IOException {
        if (StringUtils.isBlank(orderNo)) {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            return;
        }
        //修改订单状态
        this.orderInfoService.updateOrderStatus(orderNo, SystemConstant.ORDER_STATUS_UNPAID, SystemConstant.ORDER_STATUS_CANCEL);
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }
}
